<!--
 * @Author: xinqiao lxq1990.0716@qq.com
 * @Date: 2023-03-06 15:22:55
 * @LastEditors: 何伟伦 weilun@ssc-hn.com
 * @LastEditTime: 2024-05-06
 * @FilePath: \vue-vben-admin-thin\src\views\sys\login\register.vue
 * @Description: 注册
-->
<script lang="ts" setup>
  import { message } from 'ant-design-vue'
  import md5 from 'js-md5'
  import { reactive, ref } from 'vue'
  import { useRouter } from 'vue-router'

  import { requestRegister } from '/@/api/system/ysys-user/unAuth/account'
  import { IdentityTypeEnum } from '/@/api/system/ysys-user/unAuth/account/enum'
  import { requestSendEmailRegisterCode, requestSendSmsCode } from '/@/api/system/ysys-user/unAuth/sms'
  import { HttpCodeEnum } from '/@/enums/httpEnum'
  import { LoginImgEnum } from '/@/enums/img/sysEnum'
  import { RouterPathEnum } from '/@/enums/routerEnum'

  const router = useRouter()
  const activeKey = ref(0)
  const tabs = [
    {
      ind: 0,
      key: 10,
      title: '手机号',
      phone: '',
      phoneCode: '',
      name: '',
      pwd: '',
      pwdAgain: '',
      checked: false,
      sendCode: async () => {
        const { responseCode } = await requestSendSmsCode({ phoneNum: state.phone })
        return { responseCode }
      },
    },
    {
      ind: 1,
      key: 20,
      title: '邮箱',
      phone: '',
      phoneCode: '',
      name: '',
      pwd: '',
      pwdAgain: '',
      checked: false,
      sendCode: async () => {
        const { responseCode } = await requestSendEmailRegisterCode({ email: state.phone })
        return { responseCode }
      },
    },
  ]
  const state = reactive({
    loading: false,
    phone: '',
    phoneCode: '',
    pwd: '',
    pwdAgain: '',
    checked: false,
    name: '',
  })

  const secondTip = ref<number>(0)

  /**
   * 获取短信验证码
   */
  const getPhoneCode = async () => {
    if (secondTip.value) return
    if (state.phone === '') {
      message.error(`请输入${tabs[activeKey.value].title}`)
      return
    }
    const { responseCode } = await tabs[activeKey.value].sendCode()
    if (responseCode === HttpCodeEnum.SUCCESS) resetSecond()
  }

  /**
   * 验证码重置及倒计时
   */
  const resetSecond = async () => {
    secondTip.value = 60
    const intervalId = setInterval(() => {
      if (secondTip.value > 0) {
        secondTip.value--
      } else {
        clearInterval(intervalId)
      }
    }, 1000)
  }

  /**
   * 校验
   * @returns
   */
  const valid = () => {
    const regex = /^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z\s]+$)\S{6,20}$/
    if (state.name === '') {
      message.error('请输入用户名')
      return false
    }
    if (state.phone === '') {
      message.error(`请输入${tabs[activeKey.value].title}`)
      return false
    }
    if (state.phoneCode === '') {
      message.error('请输入验证码')
      return false
    }
    if (state.pwd === '') {
      message.error('请输入密码')
      return false
    }
    if (!regex.test(state.pwd)) {
      message.error('密码需6-20位字母、数字、特殊字符至少两种组合，不能包含空格')
      return false
    }
    if (state.pwdAgain === '') {
      message.error('请再次输入密码')
      return false
    }
    if (state.pwd !== state.pwdAgain) {
      message.error('两次密码不一致')
      return false
    }
    if (!state.checked) {
      message.error('请勾选同意用户隐私和服务条款')
      return false
    }
    return true
  }

  /**
   * 注册
   */
  const doRegister = async () => {
    if (!valid()) return
    state.loading = true
    const { responseCode } = await requestRegister({
      identityType: activeKey.value === 0 ? IdentityTypeEnum.PHONE : IdentityTypeEnum.EMAIL,
      userName: state.phone,
      phoneCode: state.phoneCode,
      password: md5(state.pwd),
      name: state.name,
    })
    state.loading = false
    if (responseCode === HttpCodeEnum.SUCCESS) {
      message.success('注册成功')
      router.push(RouterPathEnum.LOGIN)
    }
  }

  /**
   * 已有账号，跳转登录
   */
  const doLogin = async () => {
    router.push(RouterPathEnum.LOGIN)
  }

  /**
   * 用户协议
   */
  const doAgreement = async () => {
    const ageUrl = router.resolve({
      path: '/agreement',
    })
    window.open(ageUrl.href, '_blank')
  }

  // 切换面板
  const changePane = (index) => {
    // 切换tab保留各自的输入值
    let ind = index === 1 ? 0 : 1
    tabs[ind].phone = state.phone
    tabs[ind].phoneCode = state.phoneCode
    tabs[ind].name = state.name
    tabs[ind].pwd = state.pwd
    tabs[ind].pwdAgain = state.pwdAgain
    tabs[ind].checked = state.checked
    state.phone = tabs[index].phone
    state.phoneCode = tabs[index].phoneCode
    state.name = tabs[index].name
    state.pwd = tabs[index].pwd
    state.pwdAgain = tabs[index].pwdAgain
    state.checked = tabs[index].checked
    secondTip.value = 0
  }
</script>

<template>
  <div class="register">
    <div class="content">
      <div class="login-logo">
        <img :src="LoginImgEnum.LOGIN_LOGO_NEW" />
      </div>
      <a-tabs v-model:activeKey="activeKey" @change="changePane">
        <a-tab-pane v-for="tab in tabs" :key="tab.ind" :tab="tab.title" />
      </a-tabs>
      <a-input class="content-input" style="margin-top: 0" autocomplete="off" type="text" v-model:value="state.name" placeholder="请输入用户名" />
      <a-input class="content-input" autocomplete="off" type="text" v-model:value="state.phone" :placeholder="`请输入${tabs[activeKey].title}`" :maxlength="activeKey === 0 ? 11 : 320"/>
      <a-input class="content-input" autocomplete="new-password" v-model:value="state.phoneCode" :placeholder="`请输入${activeKey === 0 ? '短信' : '邮箱'}验证码`">
        <template #suffix>
          <a class="content-code" @click="getPhoneCode()">{{ secondTip ? `${secondTip}秒` : `获取验证码` }}</a>
        </template>
      </a-input>
      <a-input-password autocomplete="new-password" class="content-input" v-model:value="state.pwd" placeholder="请设置6-20位登录密码" />

      <a-input-password autocomplete="off" auto class="content-input" v-model:value="state.pwdAgain" placeholder="请再次输入6-20位登录密码" />
      <div class="agreement-container">
        <a-radio v-model:checked="state.checked" /><span>勾选同意<a class="agree-link" @click="doAgreement">《用户隐私和服务条款》</a></span>
      </div>
      <a-button class="content-button" type="primary" block :loading="state.loading" @click="() => doRegister()">注册</a-button>
      <div class="register-container">
        <span>已有账号？<a class="login-link" @click="() => doLogin()">立即登录</a></span>
      </div>
    </div>
    <div class="copyright">Copyright 2024 @ 云海链控股股份有限公司 琼ICP备19003338号-3</div>
  </div>
</template>

<style lang="less" scoped>
  .register {
    width: 100vw;
    min-height: 100vh;
    background: url('/@/assets/images/sys/login/login/bg.png') no-repeat;
    background-size: cover;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  ::v-deep(.ant-input) {
    background: transparent !important;
    color: rgb(255 255 255 / 85%);
    box-shadow: none;

    &::placeholder {
      color: rgb(255 255 255 / 25%);
    }
  }

  ::v-deep(.ant-input-suffix) {
    span {
      color: #fff;
    }
  }

  .content {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 44px 54px 20px;
    width: 440px;
    height: 620px;
    background: url('/@/assets/images/sys/login/login/login-container.png') no-repeat;
    border-radius: 12px;
    z-index: 2;

    .login-logo {
      margin: 0 auto;

      img {
        height: 112px;
        width: 150px;
      }
    }

    :deep(.ant-tabs-tab) {
      color: #fff;
    }

    :deep(.ant-tabs-top > .ant-tabs-nav::before) {
      border-bottom: none;
    }

    .content-input {
      border: none;
      border-bottom: 1px solid #4e5969;
      background: transparent;
      font-size: 14px;
      margin-top: 20px;
      font-weight: 400;
      padding-left: 0;
      box-shadow: none;
    }

    .agreement-container {
      display: flex;
      flex-direction: row;
      color: rgb(255 255 255 / 45%);
      margin-top: 20px;

      .agree-link {
        font-weight: 400;
        color: #13c2c2;
      }
    }

    .register-container {
      display: flex;
      flex-direction: row;
      justify-content: center;
      color: rgb(255 255 255 / 45%);
      margin-top: 12px;

      .login-link {
        font-weight: 400;
        color: #13c2c2;
      }
    }

    > .content-button {
      height: 44px;
      margin-top: 20px;
      color: #002329;
      background: linear-gradient(90deg, #36cfc9 0%, #13c2c2 100%);
    }
  }

  .copyright {
    position: absolute;
    left: 50%;
    bottom: 40px;
    transform: translate(-50%, 0);
    color: rgb(255 255 255 / 65%);
    font-size: 12px;
    z-index: 1;
  }
</style>
